Learn Go in 10 minutes
Go (also known as Golang) is a statically typed, compiled programming language designed at Google. It’s known for its simplicity, efficiency, and excellent support for concurrency. This tutorial will help you quickly learn Go programming.
1. Writing Your First Go Program
Let’s start with a simple program. Create a file named hello.go
and enter the following code:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
Save the file and run the following command in the terminal:
go run hello.go
The output will be:
Hello, World!
This simple program demonstrates Go’s basic structure:
package main
declares the package nameimport "fmt"
imports the format package for I/O operationsfunc main()
is the entry point of the programfmt.Println()
prints text to the console
2. Basic Syntax
Go has a clean and simple syntax. Unlike Python, Go uses curly braces {}
to define code blocks and requires semicolons at the end of statements (though they’re usually inserted automatically).
// This is a single-line comment
fmt.Println("Hello, World!")
/*
This is a multi-line comment
spanning multiple lines
*/
Basic syntax rules in Go:
- Code Blocks: Defined by curly braces
{}
- Comments: Single-line comments start with
//
, multi-line with/* */
- Statements: End with semicolons (automatically inserted)
- Package Declaration: Every file starts with a package declaration
3. Variables and Data Types
Go is statically typed, meaning you must declare variable types. However, Go supports type inference with the :=
operator.
Variable declaration methods:
// Explicit type declaration
var name string = "John"
var age int = 25
// Type inference
name := "John"
age := 25
// Multiple variable declaration
var x, y int = 10, 20
x, y := 10, 20
Go’s main basic data types:
- Integer types:
int
,int8
,int16
,int32
,int64
,uint
,uint8
,uint16
,uint32
,uint64
,uintptr
- Float types:
float32
,float64
- String:
string
- Boolean:
bool
- Complex types:
complex64
,complex128
3.1 Numeric Types
Go provides various numeric types for different use cases:
// Integer types
var age int = 25
var smallNumber int8 = 127
var largeNumber int64 = 9223372036854775807
// Float types
var temperature float32 = 36.5
var pi float64 = 3.14159265359
// Complex numbers
var complexNum complex64 = 3 + 4i
3.2 String Type
Strings in Go are sequences of bytes and are immutable:
// String declaration
var greeting string = "Hello, Go!"
name := "Alice"
// String operations
fmt.Println(len(greeting)) // String length
fmt.Println(greeting[0]) // Access first character (byte)
fmt.Println(greeting[0:5]) // String slicing
fmt.Println(strings.ToUpper(name)) // Convert to uppercase
3.3 Boolean Type
Boolean type has two values: true
and false
:
var isActive bool = true
var isComplete bool = false
// Boolean operations
result1 := true && false // false
result2 := true || false // true
result3 := !true // false
4. Constants
Constants are declared using the const
keyword and cannot be changed:
const Pi = 3.14159
const MaxUsers = 1000
// Multiple constants
const (
StatusOK = 200
StatusNotFound = 404
StatusError = 500
)
// Typed constants
const Version string = "1.0.0"
5. Data Structures
Go provides several built-in data structures for storing and manipulating data.
5.1 Arrays
Arrays are fixed-size sequences of elements of the same type:
// Array declaration
var numbers [5]int = [5]int{1, 2, 3, 4, 5}
names := [3]string{"Alice", "Bob", "Charlie"}
// Accessing elements
fmt.Println(numbers[0]) // 1
numbers[0] = 10 // Modify element
// Array length
fmt.Println(len(numbers)) // 5
5.2 Slices
Slices are dynamic arrays that can grow and shrink:
// Slice declaration
numbers := []int{1, 2, 3, 4, 5}
var emptySlice []int
// Creating slices from arrays
arr := [5]int{1, 2, 3, 4, 5}
slice := arr[1:4] // [2, 3, 4]
// Slice operations
numbers = append(numbers, 6) // Add element
numbers = append(numbers, 7, 8, 9) // Add multiple elements
// Slice capacity and length
fmt.Println(len(numbers)) // Length: 9
fmt.Println(cap(numbers)) // Capacity: 10 (may vary)
5.3 Maps
Maps are unordered collections of key-value pairs:
// Map declaration
student := map[string]interface{}{
"name": "John",
"age": 20,
"major": "Computer Science",
}
// Alternative declaration
var scores map[string]int = make(map[string]int)
scores["math"] = 95
scores["science"] = 88
// Accessing and modifying
fmt.Println(student["name"])
student["age"] = 21
student["gpa"] = 3.8
// Safe access
if phone, exists := student["phone"]; exists {
fmt.Println(phone)
} else {
fmt.Println("Phone not provided")
}
// Iterating over map
for key, value := range student {
fmt.Printf("%s: %v\n", key, value)
}
5.4 Structs
Structs are collections of fields that can have different types:
// Struct definition
type Person struct {
Name string
Age int
City string
}
// Creating struct instances
person1 := Person{"Alice", 25, "New York"}
person2 := Person{
Name: "Bob",
Age: 30,
City: "London",
}
// Accessing fields
fmt.Println(person1.Name)
person1.Age = 26
6. Operations and Operators
Go provides a rich set of operators for various computations and comparisons.
- Arithmetic Operators:
+
,-
,*
,/
,%
(modulus) - Comparison Operators:
==
,!=
,>
,<
,>=
,<=
- Logical Operators:
&&
,||
,!
- Bitwise Operators:
&
,|
,^
,<<
,>>
- Assignment Operators:
=
,+=
,-=
,*=
,/=
6.1 Arithmetic Operators
a, b := 10, 3
fmt.Printf("Addition: %d\n", a + b) // 13
fmt.Printf("Subtraction: %d\n", a - b) // 7
fmt.Printf("Multiplication: %d\n", a * b) // 30
fmt.Printf("Division: %d\n", a / b) // 3
fmt.Printf("Modulus: %d\n", a % b) // 1
6.2 Comparison Operators
x, y := 5, 10
fmt.Printf("Equal: %t\n", x == y) // false
fmt.Printf("Not equal: %t\n", x != y) // true
fmt.Printf("Greater than: %t\n", x > y) // false
fmt.Printf("Less than: %t\n", x < y) // true
6.3 Logical Operators
a, b := true, false
fmt.Printf("AND operation: %t\n", a && b) // false
fmt.Printf("OR operation: %t\n", a || b) // true
fmt.Printf("NOT operation: %t\n", !a) // false
7. Control Flow
Go provides several control flow statements to manage program execution.
7.1 if Statements
age := 20
if age >= 18 {
fmt.Println("Adult")
} else if age >= 13 {
fmt.Println("Teen")
} else {
fmt.Println("Child")
}
// if with short statement
if score := 85; score >= 90 {
fmt.Println("Grade: A")
} else if score >= 80 {
fmt.Println("Grade: B")
} else {
fmt.Println("Grade: C")
}
7.2 for Loops
Go has only one loop construct: for
// Basic for loop
for i := 0; i < 5; i++ {
fmt.Println(i)
}
// While-style loop
count := 0
for count < 5 {
fmt.Println(count)
count++
}
// Infinite loop
for {
fmt.Println("This will run forever")
break // Use break to exit
}
// Range loop (for slices, arrays, maps)
fruits := []string{"apple", "banana", "cherry"}
for index, fruit := range fruits {
fmt.Printf("%d: %s\n", index, fruit)
}
7.3 switch Statements
day := "Monday"
switch day {
case "Monday":
fmt.Println("Start of the week")
case "Friday":
fmt.Println("Weekend is near")
case "Saturday", "Sunday":
fmt.Println("Weekend!")
default:
fmt.Println("Regular day")
}
// Switch with no expression
score := 85
switch {
case score >= 90:
fmt.Println("Grade: A")
case score >= 80:
fmt.Println("Grade: B")
case score >= 70:
fmt.Println("Grade: C")
default:
fmt.Println("Grade: F")
}
8. Functions
Functions in Go are first-class citizens and support multiple return values.
8.1 Basic Functions
func greet(name string) string {
return "Hello, " + name + "!"
}
// Calling the function
message := greet("John")
fmt.Println(message)
8.2 Multiple Return Values
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("cannot divide by zero")
}
return a / b, nil
}
// Using multiple return values
result, err := divide(10, 2)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result)
}
8.3 Named Return Values
func calculateRectangle(width, height float64) (area float64, perimeter float64) {
area = width * height
perimeter = 2 * (width + height)
return // naked return
}
area, perimeter := calculateRectangle(5, 3)
fmt.Printf("Area: %.2f, Perimeter: %.2f\n", area, perimeter)
8.4 Variadic Functions
func sum(numbers ...int) int {
total := 0
for _, num := range numbers {
total += num
}
return total
}
fmt.Println(sum(1, 2, 3, 4)) // 10
fmt.Println(sum(5, 10, 15)) // 30
9. Pointers
Go has pointers but with simpler syntax than C/C++:
func modifyValue(x *int) {
*x = *x * 2
}
func main() {
value := 10
fmt.Println("Before:", value) // 10
modifyValue(&value)
fmt.Println("After:", value) // 20
}
10. Methods
Methods are functions with a receiver argument:
type Rectangle struct {
Width float64
Height float64
}
// Method with value receiver
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// Method with pointer receiver
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}
rect := Rectangle{Width: 5, Height: 3}
fmt.Println("Area:", rect.Area()) // 15
rect.Scale(2)
fmt.Println("Scaled Area:", rect.Area()) // 60
11. Interfaces
Interfaces define method signatures that types can implement:
type Shape interface {
Area() float64
Perimeter() float64
}
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return 3.14159 * c.Radius * c.Radius
}
func (c Circle) Perimeter() float64 {
return 2 * 3.14159 * c.Radius
}
func printShapeInfo(s Shape) {
fmt.Printf("Area: %.2f, Perimeter: %.2f\n", s.Area(), s.Perimeter())
}
circle := Circle{Radius: 5}
printShapeInfo(circle)
12. Error Handling
Go uses explicit error handling rather than exceptions:
func readFile(filename string) (string, error) {
data, err := os.ReadFile(filename)
if err != nil {
return "", fmt.Errorf("failed to read file %s: %w", filename, err)
}
return string(data), nil
}
content, err := readFile("example.txt")
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Content:", content)
13. Concurrency with Goroutines
Goroutines are lightweight threads managed by the Go runtime:
func worker(id int) {
for i := 0; i < 3; i++ {
fmt.Printf("Worker %d: %d\n", id, i)
time.Sleep(time.Millisecond * 100)
}
}
func main() {
// Start multiple goroutines
for i := 1; i <= 3; i++ {
go worker(i)
}
// Wait for goroutines to complete
time.Sleep(time.Second)
fmt.Println("All workers completed")
}
14. Channels
Channels are used for communication between goroutines:
func producer(ch chan<- int) {
for i := 0; i < 5; i++ {
ch <- i // Send value to channel
time.Sleep(time.Millisecond * 100)
}
close(ch) // Close channel when done
}
func consumer(ch <-chan int) {
for value := range ch {
fmt.Println("Received:", value)
}
}
func main() {
ch := make(chan int, 3) // Buffered channel
go producer(ch)
consumer(ch)
fmt.Println("Channel communication completed")
}
15. File Operations
Go provides simple methods for reading and writing files:
// Reading files
data, err := os.ReadFile("example.txt")
if err != nil {
fmt.Println("Error reading file:", err)
return
}
fmt.Println("File content:", string(data))
// Writing files
content := "Hello, Go!\n"
err = os.WriteFile("output.txt", []byte(content), 0644)
if err != nil {
fmt.Println("Error writing file:", err)
return
}
fmt.Println("File written successfully")
16. Packages and Modules
Go modules manage dependencies and package versions:
// Importing standard library packages
import (
"fmt"
"math"
"strings"
)
func main() {
fmt.Println(math.Sqrt(16)) // 4
fmt.Println(strings.ToUpper("go")) // GO
}
To create your own package, create a directory with your package name and export functions by capitalizing their names.
17. Testing
Go has built-in testing support:
// In file math_test.go
package main
import "testing"
func TestAdd(t *testing.T) {
result := add(2, 3)
expected := 5
if result != expected {
t.Errorf("add(2, 3) = %d; want %d", result, expected)
}
}
func add(a, b int) int {
return a + b
}
Run tests with: go test
18. Best Practices
- Use
gofmt
to format your code - Follow Go naming conventions (camelCase for variables, PascalCase for exports)
- Handle errors explicitly
- Use interfaces for abstraction
- Prefer composition over inheritance
- Write comprehensive tests
- Use the standard library whenever possible
This tutorial covers the essential features of Go programming. With practice, you’ll be able to build efficient and concurrent applications using Go’s powerful features.